import { isNull } from './index'
import path from 'path'
import { pick } from 'lodash-es'

/**
 * @description:返回路由分类 顶级与子级  同时不要path有*的 和 ''的路由 如果某个路由的parent的path为''字符串的话那么它就归类为一级路由 如:/dashboard就为一级路由
 * @param {Array} routes
 * @return {result}
 */
export const filterRoutes = (routes = []) => {
  const result = {
    topRoutes: [],
    childRoutes: []
  }
  for (const routeItem of routes) {
    if (routeItem.path === '' || routeItem.path.includes('*')) continue

    if (!routeItem.parent) {
      result.topRoutes.push(routeItem)
    } else if (routeItem.parent && routeItem.parent.path === '') {
      result.topRoutes.push(routeItem)
    } else {
      result.childRoutes.push(routeItem)
    }
  }
  return result
}

/* * 根据 filterRoutes后的数据，返回对应 menu 规则数组 ,当然这些数据离不开$router.getRoutes返回的数据,我们这里没有复制，因为很难复制*/
export const generateMenus = (routes = [], path = '/') => {
  // $router.getRoutes() 获取所有活跃的路由记录列表。注意只有文档中记录下来的 property 才被视为公共 API，避免使用任何其它 property，例如 regex，因为它在 Vue Router 4 中不存在。https://v3.router.vuejs.org/zh/api/#routes
  const { topRoutes, childRoutes } = filterRoutes(routes)

  let allEffectiveRoutes = [...topRoutes, ...childRoutes]
  // 重新构造新的
  allEffectiveRoutes = _structNewRoutes(allEffectiveRoutes, path)

  const pathKeyMap = {}
  for (const route of allEffectiveRoutes) {
    if (pathKeyMap[route.path] == undefined) {
      pathKeyMap[route.path] = route
    } else {
      console.warn(`route.path: ${route.path} should be an unique path`)
    }
  }

  for (const pathKey of Object.keys(pathKeyMap)) {
    const route = pathKeyMap[pathKey]

    if (!route.parent) continue

    const parentPathKey = route.parent.path
    if (pathKeyMap[parentPathKey]) {
      const children = pathKeyMap[parentPathKey].children
      // 这里得route会被相互引用从而达到只要引用一次，之后对内容添加，那么引用将被照样添加，所以只要拿到一级路由就行
      children
        ? children.push(route)
        : (pathKeyMap[parentPathKey].children = [route])
    }
  }
  const result = []
  topRoutes.forEach((item) => {
    if (pathKeyMap[item.path]) result.push(pathKeyMap[item.path])
  })
  return result
}

function _structNewRoutes(routes = [], prefixPath) {
  const pickAry = ['name', 'path', 'meta', 'alias', 'props']
  const result = []
  function loop(route) {
    let newRoute = pick(route, pickAry)
    newRoute.path = path.join(prefixPath, newRoute.path)
    if (route.parent) {
      newRoute.parent = loop(route.parent)
    }
    return newRoute
  }
  for (const route of routes) {
    result.push(loop(route))
  }
  return result
}
